package com.scalar.chiptrack.adaptor.utils;

import jxl.Workbook;
import jxl.Sheet;
import jxl.Cell;
import jxl.read.biff.BiffException;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.ArrayList;

/**
 * User: Chandu
 * Date: July 20, 2010
 * Time: 10:44:38 AM
 */
public class JXLXLSParserImpl implements Parser
{
    private ParserResult parserResult = null;
    private File file = null;
    private String sheetName = null;
    private int sheetIdx = 0;
    private int headerRowIdx = 0;
    private int dataStartRowIdx = 1;
    private boolean headingsCaseSensitive;
    private ArrayList sheetNamesList = null;

    public JXLXLSParserImpl( File file )
    {
         this.file = file;
    }
    public JXLXLSParserImpl( File file, String sheetName )
    {
        this.file = file;
        this.sheetName = sheetName;
    }
    public JXLXLSParserImpl( File file, int sheetIdx )
    {
        this.file = file;
        this.sheetIdx = sheetIdx;
    }
    public JXLXLSParserImpl( String filePath, String fileName )
    {
        this.file = new File ( (filePath != null) ? (filePath + "/" + fileName) : fileName );
    }
    public JXLXLSParserImpl( String filePath, String fileName, String sheetName )
    {
        this.file = new File ( (filePath != null) ? (filePath + "/" + fileName) : fileName );
        this.sheetName = sheetName;
    }
    public JXLXLSParserImpl( String filePath, String fileName, int sheetNo )
    {
        this.file = new File ( (filePath != null) ? (filePath + "/" + fileName) : fileName );
        this.sheetIdx = sheetNo;
    }

    public ParserResult parse( String sheetName ) throws Exception
    {
        this.sheetName = sheetName;

        return parse();
    }
    public ParserResult parse( int sheetIndex ) throws Exception
    {
        sheetName = null;
        this.sheetIdx = sheetIndex;

        return parse();
    }

    public ParserResult parse() throws Exception
    {
        Workbook workbook 	        = Workbook.getWorkbook( file );
        Sheet sheet 		        = null;
        if ( sheetName == null )
        {
            sheet = workbook.getSheet(sheetIdx);
        }
        else
        {
            sheet = workbook.getSheet ( sheetName );
        }
        Cell[] cells 			    = null;
        int noOfRows                = sheet.getRows();
        ParserResultJXLXLSImpl parserResult = new ParserResultJXLXLSImpl();
        LinkedList headings = new LinkedList();
        if ( noOfRows <= dataStartRowIdx )
        {
            parserResult.setHeadingsCaseSensitive(headingsCaseSensitive);
            parserResult.setHeadings( null );
            parserResult.setData(  new Object[0][0] );
            this.parserResult = parserResult;
            return parserResult;
        }

        if ( headerRowIdx >= 0 && noOfRows > headerRowIdx )
        {
            cells = sheet.getRow ( headerRowIdx );
            int noOfCells = cells.length;
            for ( int col=0; col < noOfCells; col++ )
            {
                headings.add ( cells[col] != null ? cells[col].getContents() : null );
            }
        }

        Object[][] data = null;
        int maxNoOfCols = 0;
        for ( int rowCount = dataStartRowIdx; rowCount < noOfRows; rowCount++ )
        {
            cells = sheet.getRow( rowCount );
            if ( cells.length > maxNoOfCols )
            {
                maxNoOfCols = cells.length;
            }

        }
        data = new Object[noOfRows-dataStartRowIdx][maxNoOfCols];
        int dataRow = 0;
        for ( int rowCount = dataStartRowIdx; rowCount < noOfRows; rowCount++ )
        {
            cells = sheet.getRow( rowCount );
            for ( int dataCol = 0; dataCol < cells.length; dataCol ++ )
            {
                data[dataRow][dataCol] = cells[dataCol];
            }
            dataRow++;
        }

        parserResult.setHeadingsCaseSensitive(headingsCaseSensitive);
        parserResult.setHeadings( headings );
        parserResult.setData( data );
        this.parserResult = parserResult;
        return parserResult;
    }

    public ParserResult getParserResult()
    {
        return parserResult;
    }

    public String getSheetName() {
        return sheetName;
    }

    public int getSheetIdx() {
        return sheetIdx;
    }

    public int getHeaderRowIdx() {
        return headerRowIdx;
    }

    public void setHeaderRowIdx(int headerRowIdx) {
        this.headerRowIdx = headerRowIdx;
    }

    public int getDataStartRowIdx() {
        return dataStartRowIdx;
    }

    public void setDataStartRowIdx(int dataStartRowIdx) {
        this.dataStartRowIdx = dataStartRowIdx;
    }

    public boolean isHeadingsCaseSensitive() {
        return headingsCaseSensitive;
    }

    public void setHeadingsCaseSensitive(boolean headingsCaseSensitive) {
        this.headingsCaseSensitive = headingsCaseSensitive;
    }

    private void prePareSheetNames() throws IOException, BiffException
    {
        Sheet sheet = null;
        sheetNamesList = new ArrayList();
        Workbook workbook = Workbook.getWorkbook( file );
        for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++)
        {
            sheet = workbook.getSheet(sheetIndex);

            sheetNamesList.add( sheet.getName() );
        }
    }

    public ArrayList getSheetNamesList() throws IOException, BiffException
    {
        if ( sheetNamesList == null )
        prePareSheetNames();

        return sheetNamesList;
    }
}